package com.solution.common.redis;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.Cache;
import org.springframework.cache.support.SimpleValueWrapper;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;

import com.solution.common.config.PublicConfigUtil;
/**
 * Redis 缓存的实现类（缓存管理器通过该类操作redis数据库，进行读写操作）
 * @author llp
 * @param <T>
 */
public class RedisCache<T> implements Cache {

	private static final Logger logger=LoggerFactory.getLogger(RedisCache.class);
	
	/**
	 * redis 操作模板
	 */
	private RedisTemplate<String, Object> redisTemplate;
	/**
	 * 缓存的名称
	 */
	private String name;

	public RedisTemplate<String, Object> getRedisTemplate() {
		return redisTemplate;
	}
	
	public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
		this.redisTemplate = redisTemplate;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String getName() {
		return this.name;
	}

	@Override
	public Object getNativeCache() {
		return this.redisTemplate;
	}

	/**
	 * Redis get 操作
	 * @param key 缓存的key值
	 */
	@Override
	public ValueWrapper get(Object key) {
		logger.info("获取 redis key : {} 的值",key.toString());
		final String keyf = key.toString();
		Object object = null;
		object = redisTemplate.execute(new RedisCallback<Object>() {
			public Object doInRedis(RedisConnection connection)
					throws DataAccessException {
				try {
					byte[] key = keyf.getBytes();
					byte[] value = connection.get(key);
					if (value == null) {
						return null;
					}
					Object t = RedisSerializeUtils.kryoDeserialize(value);
					return t;
                } catch (Exception e) {
                	e.printStackTrace();
                	// 获取数据失败，或者反序列化对象异常，则清除该key
                	evict(keyf);
                	logger.error("获取redis缓存数据失败！返回空，同时清空 key：" + keyf);
                	return null;
                }
			}
		});
		return (object != null ? new SimpleValueWrapper(object) : null);
	}

	/**
	 * Redis set 操作
	 * @param key 缓存key值
	 * @param value 缓存value值
	 */
	@Override
	public void put(Object key, final Object value) {
		logger.info("设置 redis key : {} 的值",key.toString());
		final String keyf = key.toString();
		final long liveTime = Long.parseLong(PublicConfigUtil.readConfig("redis.expiration")); 
		redisTemplate.execute(new RedisCallback<Long>() {
			public Long doInRedis(RedisConnection connection)
					throws DataAccessException {
				byte[] keyb = keyf.getBytes();
				byte[] valueb = RedisSerializeUtils.kryoSerialize(value);
				connection.set(keyb, valueb);
				if (liveTime > 0) {
					connection.expire(keyb, liveTime);
				}
				return 1L;
			}
		});
	}

	
	/**
	 * Redis 清空缓存
	 * @param key 要清空缓存的key值
	 */
	@Override
	public void evict(Object key) {
		logger.info("清空redis key : {}",key);
		final String keyf = key.toString();
		redisTemplate.execute(new RedisCallback<Long>() {
			public Long doInRedis(RedisConnection connection)
					throws DataAccessException {
				return connection.del(keyf.getBytes());
			}
		});
	}

	/**
	 * 清空redis 所有key值
	 */
	@Override
	public void clear() {
		logger.info("清空redis 所有key");
		redisTemplate.execute(new RedisCallback<String>() {
			public String doInRedis(RedisConnection connection)
					throws DataAccessException {
				connection.flushDb();
				return "ok";
			}
		});
	}

	@Override
	public <T> T get(Object key, Class<T> type) {
		return null;
	}

	@Override
	public ValueWrapper putIfAbsent(Object key, Object value) {
		return null;
	}

}